package com.huishu.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huishu.commons.config.cache.RedisUtil;
import com.huishu.commons.constant.RedisKeyPrefix;
import com.huishu.commons.enums.HomeImageUrlEnum;
import com.huishu.commons.exception.BaseException;
import com.huishu.commons.exception.NotFoundException;
import com.huishu.commons.pojo.Result;
import com.huishu.commons.utlis.BeanUtils;
import com.huishu.commons.utlis.DateUtils;
import com.huishu.commons.utlis.WechatUtil;
import com.huishu.user.mapper.BuoyMapper;
import com.huishu.user.mapper.HomePageMapper;
import com.huishu.user.mapper.PopupMapper;
import com.huishu.user.pojo.dto.HomeDataDTO;
import com.huishu.user.pojo.dto.PageDataDTO;
import com.huishu.user.pojo.model.*;
import com.huishu.user.pojo.vo.HomeDataVO;
import com.huishu.user.pojo.vo.PageDataVO;
import com.huishu.user.service.HomeImageUrlService;
import com.huishu.user.service.HomePageService;
import com.huishu.user.service.NoticeService;
import com.huishu.user.service.UrlManageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator@ljj
 * @since 2023-04-14
 */
@Slf4j
@Service
public class HomePageServiceImpl extends ServiceImpl<HomePageMapper, HomePageDO> implements HomePageService {

    private static final String URL_NAME = "/pagesA/configPage/configPage?type=";

    @Autowired
    private HomeImageUrlService homeImageUrlService;

    @Autowired
    private BuoyMapper buoyMapper;

    @Autowired
    private PopupMapper popupMapper;

    @Autowired
    @Qualifier("threadPoolTaskExecutor")
    private Executor executor;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private NoticeService noticeService;

    @Autowired
    private UrlManageService urlManageService;

    @Override
    public Result homeData(HomeDataDTO homeDataDTO) {
        HomeDataVO homeDataVO = new HomeDataVO();
        try {
            String openId = WechatUtil.getOpenId(homeDataDTO.getCode());
            CompletableFuture<List<PageDataVO>> future = CompletableFuture.supplyAsync(() -> {
                // 查询首页配置
                LambdaQueryWrapper<HomePageDO> queryWrapper = Wrappers.lambdaQuery(HomePageDO.class)
                        .eq(HomePageDO::getClassify, homeDataDTO.getType())
                        .orderByAsc(HomePageDO::getSort);
                List<HomePageDO> homePages = this.list(queryWrapper);
                List<Long> homePageIds = homePages.stream().map(HomePageDO::getId).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(homePageIds)) {
                    throw new NotFoundException("无配置数据");
                }
                // 查询图片和url
                LambdaQueryWrapper<HomeImageUrlDO> queryWrapper1 = Wrappers.lambdaQuery(HomeImageUrlDO.class)
                        .in(HomeImageUrlDO::getHomePageId, homePageIds)
                        .orderByAsc(HomeImageUrlDO::getSort);
                List<HomeImageUrlDO> homeImageUrlDOS = homeImageUrlService.list(queryWrapper1);
                Map<Long, List<HomeImageUrlDO>> homeImageUrlMap = homeImageUrlDOS.stream().collect(Collectors.groupingBy(HomeImageUrlDO::getHomePageId));
                return homePages.stream().map(homePageDO -> {
                    PageDataVO pageDataVO = BeanUtils.copyProperties(homePageDO, PageDataVO.class);
                    pageDataVO.setHomeImageUrl(homeImageUrlMap.get(homePageDO.getId()));
                    return pageDataVO;
                }).collect(Collectors.toList());
            }, executor);

            CompletableFuture<List<BuoyDO>> future1 = CompletableFuture.supplyAsync(() -> {
                if (homeDataDTO.getType() == 1) {
                    // 查询浮标
                    LambdaQueryWrapper<BuoyDO> queryWrapper2 = Wrappers.lambdaQuery(BuoyDO.class)
                            .eq(BuoyDO::getIsShow, true)
                            .orderByAsc(BuoyDO::getSort);
                    return buoyMapper.selectList(queryWrapper2);
                }
                return null;
            }, executor);

            //String key = RedisKeyPrefix.POPUP_COUNT + 1;
            // 查询弹窗
            CompletableFuture<List<PopupDO>> future2 = CompletableFuture.supplyAsync(() -> {
                String key = RedisKeyPrefix.POPUP_COUNT + openId;
                List<PopupDO> popupDOList = new ArrayList<>();
                if (homeDataDTO.getType() == 1) {
                    LambdaQueryWrapper<PopupDO> queryWrapper = Wrappers.lambdaQuery(PopupDO.class)
                            .eq(PopupDO::getIsOpen, true);
                    List<PopupDO> popups = popupMapper.selectList(queryWrapper);
                    if (CollectionUtils.isNotEmpty(popups)) {
                        for (PopupDO popup : popups) {
                            Integer promptCount = popup.getPromptCount();
                            // 判断当前用户是否提示完成
                            String value = redisUtil.getString(key + ":" + popup.getId());
                            if (StringUtils.isEmpty(value) || (Integer.parseInt(value) < promptCount)) {
                                // 继续提示
                                redisUtil.set(key + ":" + popup.getId(), value == null ? 1 : Integer.parseInt(value) + 1, DateUtils.theNextDay());
                                popupDOList.add(popup);
                            }
                        }
                    }
                }
                return popupDOList;
            }, executor);
            CompletableFuture<Void> allOf = CompletableFuture.allOf(future, future1, future2);
            allOf.get();
            homeDataVO.setPageDatas(future.get());
            homeDataVO.setBuoys(future1.get());
            homeDataVO.setPopups(future2.get());
            homeDataVO.setNotice(noticeService.getOne(null));
            if (homeDataDTO.getType() == 3 || homeDataDTO.getType() == 4) {
                // 查询分享标题和图片
                LambdaQueryWrapper<BuoyDO> queryWrapper2 = Wrappers.lambdaQuery(BuoyDO.class)
                        .eq(BuoyDO::getType, homeDataDTO.getType() == 3 ? 4 : 5);
                BuoyDO one = buoyMapper.selectOne(queryWrapper2);
                homeDataVO.setShareImage(one.getShareImage());
                homeDataVO.setShareTitle(one.getShareTitle());
            }
            return Result.success(homeDataVO);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询首页数据异常!!:{}", e.getMessage());
            throw new BaseException("查询首页数据异常");
        }
    }

    @Transactional
    @Override
    public Result create(List<PageDataDTO> pageDatas) {
        for (PageDataDTO pageData : pageDatas) {
            HomePageDO homePageDO = BeanUtils.copyProperties(pageData, HomePageDO.class);
            boolean save = this.save(homePageDO);
            if (save) {
                List<HomeImageUrlDO> collect = pageData.getHomeImageUrl().stream().map(homeImageUrlDO -> homeImageUrlDO.setHomePageId(homePageDO.getId())).collect(Collectors.toList());
                homeImageUrlService.saveBatch(collect);
            }
        }
        UrlManageDO urlManageDO = new UrlManageDO();
        urlManageDO.setName(HomeImageUrlEnum.getMsgByCode(pageDatas.get(0).getClassify()));
        urlManageDO.setType(2);
        urlManageDO.setUrl(URL_NAME + pageDatas.get(0).getClassify());
        LambdaQueryWrapper<UrlManageDO> queryWrapper = Wrappers.lambdaQuery(UrlManageDO.class)
                .eq(UrlManageDO::getType, 2)
                .eq(UrlManageDO::getUrl, urlManageDO.getUrl());
        UrlManageDO one = urlManageService.getOne(queryWrapper);
        if (one == null) {
            boolean save = urlManageService.save(urlManageDO);
            if (!save) {
                throw new BaseException("添加自定义页面url失败！！");
            }
        }
        return Result.success();
    }
}
